package cn.sjxy.config.mvcExtend;

import cn.sjxy.baseLib.AjaxResult;
import cn.sjxy.baseLib.SjuException;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.sql.SQLException;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandlerController {
    @ExceptionHandler
    public AjaxResult handlerException(SjuException ex) {
        SjuException.logException(log, "执行全局异常处理3-1", ex);
        System.out.println("执行全局异常处理3-1");
        AjaxResult result = AjaxResult.error(ex.getMessage());
        //如果是登录错误，则设置返回code等于401
        if (ex.getExType() == SjuException.ExType.loginEx)
            result.setCode(401);
        result.addKey("errorType", "自定义错误3");
        return result;
    }

    @ExceptionHandler
    public AjaxResult handlerException(SQLException ex) {
        SjuException.logException(log, "执行全局异常处理3-2", ex);
        System.out.println("执行全局异常处理3-2");
        AjaxResult result = AjaxResult.error(ex.getMessage());
        result.addKey("errorType", "数据库错误");
        return result;
    }

    @ExceptionHandler
    public AjaxResult handlerException(Exception ex) {
        SjuException.logException(log, "执行全局异常处理3-3", ex);
        System.out.println("执行全局异常处理3-3");
        AjaxResult result = AjaxResult.error(ex.getMessage());
        result.addKey("errorType", "未知错误3");
        return result;
    }

    /*普通参数验证失败时*/
    @ExceptionHandler
    public AjaxResult handlerException(ConstraintViolationException ex) {
        SjuException.logException(log, "执行全局异常处理3-4", ex);
        System.out.println("执行全局异常处理3-4");
        StringBuilder msg = new StringBuilder();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
            String paramName = pathImpl.getLeafNode().getName();
            String message = constraintViolation.getMessage();
            msg.append("[").append(message).append("]");
        }
        AjaxResult result = AjaxResult.error(msg.toString());
        result.addKey("errorType", "数据验证错误");
        return result;
    }

    /*模型对象参数值绑定时*/
    @ExceptionHandler
    public AjaxResult handlerException(BindException ex) {
        SjuException.logException(log, "执行全局异常处理3-5", ex);
        System.out.println("执行全局异常处理3-5");
        //获取标注的错误信息
        String errorMsg = ex.getBindingResult().getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(" "));
        System.out.println(errorMsg);
        AjaxResult result = AjaxResult.error(errorMsg);
        result.addKey("errorType", "数据绑定错误");
        return result;
    }

}

